package com.ebupt.migu.music.roster.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.ebupt.migu.music.common.util.JsonUtils;
import com.ebupt.migu.music.common.util.excelSheet.StringUtil;
import com.ebupt.migu.restapi.EsRestHttp;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Intellij IDEA.
 * User:  liuyangyang@cd.ebupt.com
 * Date:  2020/4/14
 */
@Slf4j
@Component
public class ESutils {

    @Value("${spring.elasticsearch.port}")
    private int port;
    @Value("${spring.elasticsearch.alias}")
    private String index;
    @Value("${spring.elasticsearch.index1}")
    private String index1;
    @Value("${spring.elasticsearch.hosts}")
    private String hosts;
    @Value("${spring.elasticsearch.schema}")
    private String schema;

    /**
     * 反查
     *
     * @param str
     * @return
     */
    public String do_search(String str) {
        log.info("index:{}, hosts:{}, port:{}, schema:{}", index, hosts, port, schema);
        log.info("反查JSON：{}", str);
        String request_end_point = String.format("/%s/%s", index, "_search");
        HttpEntity entity = new NStringEntity(str, ContentType.APPLICATION_JSON);
        Request request = new Request("GET", request_end_point);
        request.setEntity(entity);
        String result = "";
        RestClientBuilder builder = RestClient.builder(new HttpHost(hosts, port, schema));
        RestClient restClient = builder.build();
        try {
            Response indexResponse = restClient.performRequest(request);
            result = EntityUtils.toString(indexResponse.getEntity());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("反查失败：{}", e.getMessage());
        } finally {
            try {
                if (restClient != null) {
                    restClient.close();
                }
            } catch (Exception e) {
                log.error("rest client close error：{}", e.getMessage());
            }
        }
        log.info("反查结果：{}", result);
        return result;
    }

    /**
     * ES反查用户信息
     *
     * @param paramValue
     * @param paramType  1-msisdn； 2-uuid
     * @return
     */
    public Map<String, Object> inverse_search(String paramValue, String paramType) {
        log.info("反查参数：{}，参数类型：{}", paramValue, paramType);
        //拼装dsl json语句
//        JSONObject cons = new JSONObject();
//        cons.put("size", 1);
//        JSONObject match = new JSONObject();
//        JSONObject param = new JSONObject();
//        if ("1".equals(paramType)) {
//            param.put("msisdn", paramValue);
//        }
//        if ("2".equals(paramType)) {
//            param.put("uid", paramValue);
//        }
//        match.put("match", param);
//        cons.put("query", match);
        // 反查
        EsRestHttp er = new EsRestHttp();
        String result = "1".equals(paramType) ? er.search(index,"msisdn",paramValue,1) :
                er.search(index,"uid",paramValue,1);
        log.info("反查结果：{}", result);
//        String result = do_search(cons.toString());
        JSONObject jsonObject = new JSONObject(result);
        JSONObject hits = jsonObject.getJSONObject("hits");
        JSONObject tj = hits.getJSONObject("total");
        int total = Integer.parseInt(tj.getStr("value"));
//        Integer total = Integer.parseInt(hits.getStr("total"));
        JSONArray users = hits.getJSONArray("hits");
        JSONObject source = null;
        Map<String, Object> user = new HashMap<>();
        if (total == 0) {
            if ("1".equals(paramType)) {
                user.put("msisdn", paramValue);
                user.put("uuid", "");
            }
            if ("2".equals(paramType)) {
                user.put("msisdn", "");
                user.put("uuid", paramValue);
            }
            user.put("idfa", "");
            user.put("imei", "");
        } else {
            JSONObject obj = users.getJSONObject(0);
            source = obj.getJSONObject("_source");
            user.put("uuid", source.getStr("uid"));
            user.put("msisdn", source.getStr("msisdn"));
            user.put("idfa", source.getStr("idfa"));
            user.put("imei", source.getStr("imei"));
        }
        log.info("结果参数：{}", user.toString());
        return user;
    }

    /**
     * 查询用户名
     *
     * @param paramValue 参数值
     * @param paramType  参数类型 1-msisdn； 2-uuid
     * @return
     */
    public String serachUserName(String paramValue, String paramType) {
        log.info("反查参数：{}，参数类型：{}", paramValue, paramType);
        //拼装dsl json语句
        JSONObject cons = new JSONObject();
        cons.put("size", 1);
        JSONObject match = new JSONObject();
        JSONObject param = new JSONObject();
        if ("1".equals(paramType)) {
            param.put("msisdn", paramValue);
        }
        if ("2".equals(paramType)) {
            param.put("uid", paramValue);
        }
        match.put("match", param);
        cons.put("query", match);
        // 反查
        String result = do_search(cons.toString());
        JSONObject jsonObject = new JSONObject(result);
        JSONObject hits = jsonObject.getJSONObject("hits");
        Integer total = Integer.parseInt(hits.getStr("total"));
        JSONArray users = hits.getJSONArray("hits");
        JSONObject source = null;
        String userName = null;
        if (total != 0) {
            JSONObject obj = users.getJSONObject(0);
            source = obj.getJSONObject("_source");
            userName = String.valueOf(source.get("user_name"));
        }
        log.info("结果参数:{}", userName);
        return userName;
    }

    /**
     * 根据歌手id 获取uid集合
     *
     * @param str
     * @return
     */
    public List<String> getUid(String str) {
        String strs = "";
        int size = 1000;
        if (!StringUtil.isNullOrBlank(str)) {
            JSONObject cons = new JSONObject();
            JSONObject param = new JSONObject();
            JSONObject match = new JSONObject();
            param.put("singer_id", str);
            match.put("match", param);
            cons.put("size", size);
            cons.put("query", match);
            cons.put("sort", "_doc");
            strs = cons.toString();
        }
        String request_end_point = String.format("/%s/%s", index1, "_search?scroll=10m");
        log.info("---第一次调用request_end_point:{}", request_end_point);
        String result = do_singerList(strs, request_end_point, "GET");
        log.info("---第一次调用result:{}", result);
        List<String> list = new ArrayList<>();
        List<String> scrollList = new ArrayList<>();
        if (result != null) {
            JSONObject jsonObject = new JSONObject(result);
            JSONObject hits = jsonObject.getJSONObject("hits");
            Integer total = Integer.parseInt(hits.getStr("total"));
            JSONArray users = hits.getJSONArray("hits");
            Map resultMap;
            JSONObject jsonObjects;
            for (int i = 0, j = users.size(); i < j; i++) {
                jsonObjects = new JSONObject(users.get(i).toString());
                resultMap = JsonUtils.json2Obj(jsonObjects.get("_source").toString(), Map.class);
                list.add(resultMap.get("uid").toString());
            }
            int start = 0;
            int max = 0;
            if (total > 0) {
                if (total % size > 0) {
                    max = total / size + 1;
                }else {
                    max = total / size;
                }
            }
            log.info("---可执行次数:{}", max);
            String scroll_id;
            while (start < max - 1) {
                if (jsonObject.containsKey("_scroll_id")) {
                    scroll_id = jsonObject.get("_scroll_id").toString();
                    scrollList.add(scroll_id);
                    request_end_point = String.format("/%s/%s", "_search", "scroll?scroll=2m&scroll_id=" + scroll_id);
                    result = do_singerList("", request_end_point, "GET");
                    jsonObject = new JSONObject(result);
                    hits = jsonObject.getJSONObject("hits");
                    total = Integer.parseInt(hits.getStr("total"));
                    log.info("总数:{}", total);
                    users = hits.getJSONArray("hits");
                    for (int i = 0, j = users.size(); i < j; i++) {
                        jsonObjects = new JSONObject(users.get(i).toString());
                        resultMap = JsonUtils.json2Obj(jsonObjects.get("_source").toString(), Map.class);
                        list.add(resultMap.get("uid").toString());
                    }
                    start++;
                }
            }
            if (scrollList != null && !scrollList.isEmpty()) {
                log.info("------删除_scroll_id---------------");
                request_end_point = String.format("/%s/%s", "_search", "scroll");
                result = do_singerList(delete(scrollList), request_end_point, "DELETE");
                log.info("----------------结果result:{}", result);
            }
            // 删除上一次的 _scroll_id
            log.info("---------------执行结束，uid长度:{}", list.size());
        }
        return list;
    }

    //  删除 _scroll_id

    private static String delete(List<String> list) {
        String[] strings = new String[list.size()];
        list.toArray(strings);
        JSONObject cons = new JSONObject();
        cons.put("scroll_id", strings);
        return cons.toString();
    }

    /**
     * 歌手id反查 关注的人群
     *
     * @param str
     * @return
     */
    public String do_singerList(String str, String request_end_point, String type) {
        log.info("index:{}, hosts:{}, port:{}, schema:{}", index1, hosts, port, schema);
        log.info("关注歌手 反差json:{}", str);
        HttpEntity entity = new NStringEntity(str, ContentType.APPLICATION_JSON);
        Request request = new Request(type, request_end_point);
        request.setEntity(entity);
        String result = "";
        RestClientBuilder builder = RestClient.builder(new HttpHost(hosts, port, schema));
        RestClient restClient = builder.build();
        try {
            Response indexResponse = restClient.performRequest(request);
            result = EntityUtils.toString(indexResponse.getEntity());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("反查失败：{}", e.getMessage());
        } finally {
            try {
                if (restClient != null) {
                    restClient.close();
                }
            } catch (Exception e) {
                log.error("rest client close error：{}", e.getMessage());
            }
        }
        log.info("反查结果：{}", result);
        return result;
    }


}
